package com.prp.bo;

import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.hibernate.Transaction;

import com.prp.db.DAOFactory;
import com.prp.db.HibernateSessionFactory;
import com.prp.db.idao.IRecommendationEntityDAO;
import com.prp.db.idao.ISubjectCategoryDAO;
import com.prp.db.idao.ISubjectChildCategoryDAO;
import com.prp.db.idao.ISubjectCommentDAO;
import com.prp.db.idao.ISubjectRecommendationDAO;
import com.prp.db.idao.IUserInformationDAO;
import com.prp.db.po.RecommendationEntity;
import com.prp.db.po.SubjectCategory;
import com.prp.db.po.SubjectChildCategory;
import com.prp.db.po.SubjectComment;
import com.prp.db.po.SubjectRecommendation;
import com.prp.gwt.client.vo.Comment;
import com.prp.gwt.client.vo.CommentList;
import com.prp.gwt.client.vo.SubjectRecommendList;

public class SubjectRecommend {

	public static SubjectRecommendList getSubjectRecommendList(int entityId) {
		ISubjectRecommendationDAO srDao = DAOFactory.getDAOFactory()
				.getSubjectRecommendationDAO();
		IUserInformationDAO usrDao = DAOFactory.getDAOFactory()
				.getUserInformationDAO();
		ISubjectCommentDAO cmtDao = DAOFactory.getDAOFactory()
				.getSubjectCommentDAO();
		List<SubjectRecommendation> list = srDao
				.findByRecommendEntityId(entityId);
		SubjectRecommendList srlist = new SubjectRecommendList();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		for (SubjectRecommendation sr : list)
			srlist.add(parse(sr, true));
		return srlist;
	}

	public static com.prp.gwt.client.vo.SubjectRecommend getSubjectRecommend(
			int id) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		ISubjectRecommendationDAO srDao = factory.getSubjectRecommendationDAO();
		SubjectRecommendation sr = srDao.findById(id);
		if (sr == null)
			return null;
		return parse(sr, false);
	}

	private static String getSummary(String content) {
		if (content == null || content.trim().equals("")) {
			return "";
		}
		String str = content.replaceAll("\\&[a-zA-Z]{1,10};", "").replaceAll(
				"<[^>]*>", "");
		str = str.replaceAll("[(/>)<]", "");
		if (str.length() < 100)
			return str;
		return str.substring(0, 100) + "...";
	}

	public static CommentList getCommentList(int subjectId) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		ISubjectCommentDAO dao = factory.getSubjectCommentDAO();
		List<SubjectComment> list = dao.findByToSubjectId(subjectId);
		CommentList commentList = new CommentList();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		for (SubjectComment c : list) {
			Comment comment = new Comment();
			comment.setContent(c.getContent());
			comment.setDate(df.format(c.getDate()));
			comment.setId(c.getCommentId());
			comment.setUser(User.parse(User.getUser(c.getCommentUserId())));
			comment.setScore(c.getScore());
			commentList.add(comment);
		}
		return commentList;
	}

	public static void createComment(int subjectId, int userId, String content,
			int score) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		ISubjectCommentDAO dao = factory.getSubjectCommentDAO();
		ISubjectRecommendationDAO reDao = factory.getSubjectRecommendationDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			if (reDao.findById(subjectId) == null) {
				return;
			}
			SubjectComment comment = new SubjectComment();
			comment.setCommentUserId(userId);
			comment.setContent(content);
			comment.setDate(new Date());
			comment.setToSubjectId(subjectId);
			if (score < 1 || score > SNSConstants.MAX_SCORE_RECORD)
				score = 10;
			comment.setScore(score);
			dao.save(comment);
			SubjectRecommendation sr = reDao.findById(subjectId);
			sr.setReplyNum(sr.getReplyNum() + 1);
			reDao.attachDirty(sr);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			HibernateSessionFactory.getSession().close();
		}
	}

	public static int createRecommend(int entityId, int userId, String title,
			String content) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		ISubjectRecommendationDAO dao = factory.getSubjectRecommendationDAO();
		IRecommendationEntityDAO reDao = factory.getRecommendationEntityDAO();
		RecommendationEntity entity = reDao.findById(entityId);
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			if (entity == null)
				return -1;
			SubjectRecommendation recommend = new SubjectRecommendation();
			recommend.setCategoryChildId(entity.getChildCategoryId());
			recommend.setClickFreq(0);
			recommend.setContent(content);
			recommend.setDate(new Date());
			recommend.setPublishId(userId);
			recommend.setRecommendEntityId(entityId);
			recommend.setReplyNum(0);
			recommend.setSubjectTitle(title);
			recommend.setWaitingTime(0);
			dao.save(recommend);
			tx.commit();
			return recommend.getRecommendationId();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return -1;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
	}

	public static SubjectRecommendList getTopRecommend() {
		List<com.prp.db.po.SubjectRecommendation> list = Recommendation
				.getSubjectRecommendationRecommend(10);
		IUserInformationDAO usrDao = DAOFactory.getDAOFactory()
				.getUserInformationDAO();
		SubjectRecommendList srlist = new SubjectRecommendList();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		for (SubjectRecommendation sr : list)
			srlist.add(parse(sr, true));
		return srlist;
	}

	public static SubjectRecommendList getUserSubjectRecommend(int userId) {
		List<com.prp.db.po.SubjectRecommendation> list = Recommendation
				.getSubjectRecommend(10, userId);
		IUserInformationDAO usrDao = DAOFactory.getDAOFactory()
				.getUserInformationDAO();
		SubjectRecommendList srlist = new SubjectRecommendList();
		for (SubjectRecommendation sr : list)
			srlist.add(parse(sr, true));
		return srlist;
	}

	public static SubjectRecommendList getUserRecentRecommend(int userId) {
		ISubjectRecommendationDAO srDao = DAOFactory.getDAOFactory()
				.getSubjectRecommendationDAO();
		List<SubjectRecommendation> list = srDao.findByPublishId(userId);
		Collections.sort(list, new Comparator<SubjectRecommendation>() {
			@Override
			public int compare(SubjectRecommendation o1,
					SubjectRecommendation o2) {
				return o2.getDate().compareTo(o1.getDate());
			}
		});
		SubjectRecommendList srlist = new SubjectRecommendList();
		for (SubjectRecommendation sr : list)
			srlist.add(parse(sr, true));
		return srlist;
	}

	public static void deleteRecommendation(int subjectId) {
		ISubjectRecommendationDAO srDao = DAOFactory.getDAOFactory()
				.getSubjectRecommendationDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			srDao.delete(srDao.findById(subjectId));
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			HibernateSessionFactory.getSession().close();
		}
	}
	
	private static com.prp.gwt.client.vo.SubjectRecommend parse(
			SubjectRecommendation sr, boolean isSummary) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		IRecommendationEntityDAO reDao = factory.getRecommendationEntityDAO();
		ISubjectChildCategoryDAO sccDao = factory.getSubjectChildCategoryDAO();
		ISubjectCategoryDAO scDao = factory.getSubjectCategoryDAO();
		IUserInformationDAO usrDao = factory.getUserInformationDAO();
		ISubjectCommentDAO cmtDao = factory.getSubjectCommentDAO();
		com.prp.gwt.client.vo.SubjectRecommend vsr = new com.prp.gwt.client.vo.SubjectRecommend();
		if (!isSummary) {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
			vsr.setId(sr.getRecommendationId());
			vsr.setUser(User.parse(usrDao.findById(sr.getPublishId())));
			vsr.setTitle(sr.getSubjectTitle());
			vsr.setContent(sr.getContent());
			vsr.setClickFreq(sr.getClickFreq());
			vsr.setReplyNum(sr.getReplyNum());
			vsr.setDate(df.format(sr.getDate()));
			vsr.setUser(User.parse(User.getUser(sr.getPublishId())));
			vsr.setEntityId(sr.getRecommendEntityId());
			vsr.setCategoryChildId(sr.getCategoryChildId());
			RecommendationEntity entity = reDao.findById(sr
					.getRecommendEntityId());
			vsr.setEntityName(entity.getEntityName());
			SubjectChildCategory scc = sccDao.findById(sr.getCategoryChildId());
			vsr.setCategoryChildName(scc.getChildCategoryName());
			vsr.setCategoryId(scc.getCategroyId());
			SubjectCategory sc = scDao.findById(scc.getCategroyId());
			vsr.setCategoryName(sc.getCategoryName());
			Double score = cmtDao.getAverageScore(vsr.getId());
			if (score == null)
				score = (double) SNSConstants.MAX_SCORE_RECORD;
			vsr.setScore(score);
		} else {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			vsr.setTitle(sr.getSubjectTitle());
			vsr.setUser(User.parse(usrDao.findById(sr.getPublishId())));
			vsr.setId(sr.getRecommendationId());
			vsr.setContent(getSummary(sr.getContent()));
			vsr.setClickFreq(sr.getClickFreq());
			vsr.setReplyNum(sr.getReplyNum());
			vsr.setDate(df.format(sr.getDate()));
			vsr.setEntityId(sr.getRecommendEntityId());
			RecommendationEntity entity = reDao.findById(sr
					.getRecommendEntityId());
			vsr.setEntityName(entity.getEntityName());
			Double score = cmtDao.getAverageScore(vsr.getId());
			if (score == null)
				score = (double) SNSConstants.MAX_SCORE_RECORD;
			vsr.setScore(score);
		}
		return vsr;
	}

	public static void addOneClick(int subjectId) {
		ISubjectRecommendationDAO srDao = DAOFactory.getDAOFactory()
				.getSubjectRecommendationDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			SubjectRecommendation sr = srDao.findById(subjectId);
			sr.setClickFreq(sr.getClickFreq() + 1);
			srDao.attachDirty(sr);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			HibernateSessionFactory.getSession().close();
		}
	}

}
